package app.caihan.scframe.base.activity

import android.os.Bundle
import androidx.core.util.forEach
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import app.caihan.scframe.base.viewmodel.BaseViewModel
import app.caihan.scframe.common.loadinghelper.LoadingHelper
import app.caihan.scframe.databind.DataBindingConfig

/**
 * ViewModel 和 DataBinding Activity基类，把ViewModel注入进来即可
 * 单一职责UI,
 * databinding绑定数据
 * viewModel用于UI层与数据层的沟通,它的职责就是帮UI层托管数据,保持单项依赖
 * UI层逻辑请写在activity里面,不要写在viewModel里,避免因为持有一些界面引用导致内存泄漏
 *
 * @author Seven-C
 * @date 2020/7/27
 */
abstract class BaseVmDbActivity<VM : BaseViewModel> : BaseVmActivity<VM>() {

    private lateinit var mBinding: ViewDataBinding

    /**
     * 这边有个强迫症,为了让子类重写相关方法的时候按照指定的顺序,因此这边做了如下处理
     */
    abstract override fun bindLayoutId(): Int

    abstract fun getDataBindingConfig(): DataBindingConfig

    abstract override fun initView(savedInstanceState: Bundle?)

    abstract override fun createObserver()

    /**
     * 警惕使用。非必要情况下，尽可能不在子类中拿到 binding 实例乃至获取 view 实例。使用即埋下隐患。
     * 目前的方案是在 debug 模式下，对获取实例的情况给予提示。
     *
     *
     * 如果这样说还不理解的话，详见 (https://xiaozhuanlan.com/topic/9816742350) 和 (https://xiaozhuanlan.com/topic/2356748910)
     *
     * @return mBinding
     */
    protected open fun getBinding(): ViewDataBinding {
        return mBinding
    }

    override fun useDataBinding(): Boolean {
        return true
    }



    /**
     * 创建DataBinding
     */
    override fun initDataBind() {
        val dataBindingConfig = getDataBindingConfig()
        mBinding = DataBindingUtil.setContentView(this, bindLayoutId())
        mBinding.lifecycleOwner = this
        mBinding.setVariable(dataBindingConfig.vmVariableId, mViewModel)
        dataBindingConfig.bindingParams.forEach { i: Int, any: Any ->
            mBinding.setVariable(i, any)
        }
    }

    override fun initLoadingHelper() {
        loadingHelper = LoadingHelper(mBinding.root)
    }

}